/*-------------------------------------------------------------------------
 *
 * pgfnames.c
 *	  目录处理函数
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/common/pgfnames.c
 *
 *-------------------------------------------------------------------------
 */

#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif

#include <dirent.h>

#ifndef FRONTEND
#define pg_log_warning(...) elog(WARNING, __VA_ARGS__)
#else
#include "common/logging.h"
#endif

/*
 * pgfnames
 *
 * 返回参数目录中对象名称的列表。调用者
 * 必须稍后调用pgfnames_cleanup来释放此
 * 函数分配的内存。
 */
char	  **
pgfnames(const char *fc_path)
{
	DIR		   *fc_dir;
	struct dirent *fc_file;
	char	  **fc_filenames;
	int			fc_numnames = 0;
	int			fc_fnsize = 200;	/* 适合许多小型数据库 */

	fc_dir = opendir(fc_path);
	if (fc_dir == NULL)
	{
		pg_log_warning("could not open directory \"%s\": %m", fc_path);
		return NULL;
	}

	fc_filenames = (char **) palloc(fc_fnsize * sizeof(char *));

	while (errno = 0, (fc_file = readdir(fc_dir)) != NULL)
	{
		if (strcmp(fc_file->d_name, ".") != 0 && strcmp(fc_file->d_name, "..") != 0)
		{
			if (fc_numnames + 1 >= fc_fnsize)
			{
				fc_fnsize *= 2;
				fc_filenames = (char **) repalloc(fc_filenames,
											   fc_fnsize * sizeof(char *));
			}
			fc_filenames[fc_numnames++] = pstrdup(fc_file->d_name);
		}
	}

	if (errno)
		pg_log_warning("could not read directory \"%s\": %m", fc_path);

	fc_filenames[fc_numnames] = NULL;

	if (closedir(fc_dir))
		pg_log_warning("could not close directory \"%s\": %m", fc_path);

	return fc_filenames;
}


/*
 *	pgfnames_cleanup
 *
 *	释放用于文件名的内存
 */
void pgfnames_cleanup(char **fc_filenames)
{
	char	  **fc_fn;

	for (fc_fn = fc_filenames; *fc_fn; fc_fn++)
		pfree(*fc_fn);

	pfree(fc_filenames);
}
